#pragma once

#include <map>
#include "ThreadBase.h"
#include "ObserverBase.h"
#include "MemoryPool.h"
#include "IOCPDefinition.h"
#include "ClientInformation.h"
#include "CircleDequeueBase.h"

class ThreadIOCP : public ThreadBase, public ObserverBase
{
public:
	ThreadIOCP(map<int,CircleDequeueBase*> p_mapCircleQueue, ConnectionInformation* p_pcClientList);
	virtual bool OnNotify(SOCKET p_stSocket, char* p_szBuffer, unsigned int p_uiLength, unsigned int p_uiIndex);

protected:
	virtual void Run();

private:
	bool DoAccept(PER_SOCKET_CONTEXT* p_pstSocketContext, PER_IO_CONTEXT* p_pstIoContext);
	bool DoReceive(PER_SOCKET_CONTEXT* p_pstSocketContext, PER_IO_CONTEXT* p_pstIoContext);
	void AddClientToQueue(unsigned char p_ucFileTypeFlag,const int p_iFileType, unsigned char p_ucCompressType,SOCKET p_iClient);
	void DecodeFileType(SOCKET p_iSocket, FileType p_stFileType);
	bool VerifyUser(char* p_szUserInfo, unsigned int p_uiLength);
	char* GetBufferFromMemoryPool(unsigned int p_uilength, unsigned int p_uiIndex);
	PER_IO_CONTEXT* GetNewIOConetext(char* p_szBuffer, unsigned int p_uiBufferLength, OPERATION_TYPE p_eType, SOCKET p_stSocket, bool p_bNeedRelease);
	void RemoveClient(PER_IO_CONTEXT* p_pstIoContext);
	bool ReAccept(PER_IO_CONTEXT* p_pstIoContext);
	void RemoveFromQueue(SOCKET p_iClientSocket);

private:
	ConnectionInformation* m_pcClientList;
	map<int,CircleDequeueBase*> m_mapCircleQueue;
	list<SOCKET> m_lstWaitingClients;
};